import * as vscode from 'vscode';
import { HarmonyPilotComment } from './HarmonyPilotComment';
import { v4 as uuidv4 } from 'uuid';
import { HarmonyPilotCommentCollectionProvider } from './HarmonyPilotCommentCollectionProvider';

export class HarmonyPilotCommentCollection {
    constructor(collectionId: string, 
		context: vscode.ExtensionContext, functionName: string) {
		const commentController = vscode.comments.createCommentController(collectionId, collectionId);
		context.subscriptions.push(commentController);

		this.commentController = commentController;
		this.functionName = functionName;

		this.commentController.commentingRangeProvider = {
			provideCommentingRanges: (document: vscode.TextDocument, _token: vscode.CancellationToken) => {
				return this.commentRanges;
			}
		};
	}

	private commentRanges: vscode.Range[] = [];
	private commentController: vscode.CommentController;
	private functionName: string;
	private commentThreads: vscode.CommentThread[] = [];
	private theadMap: Map<string, vscode.CommentThread> = new Map();

	public async addComment(markdownContent:string, fsPath:string, startPosition: vscode.Position, endPosition: vscode.Position, replaceString: string, label?: string) {
		const thread = this.createThread(fsPath, startPosition, endPosition);
		
		const threadUuid = uuidv4();
		this.theadMap.set(threadUuid, thread);
		HarmonyPilotCommentCollectionProvider.addCollection(threadUuid, this);
		HarmonyPilotCommentCollectionProvider.addThreadToUuid(thread, threadUuid);

		// Get the document text based on the file path and position range
		const document = await vscode.workspace.openTextDocument(vscode.Uri.file(fsPath));
		const originalContent = document.getText(new vscode.Range(startPosition, endPosition));
		const comment = this.createComment(threadUuid, markdownContent, originalContent, thread, replaceString, label);
		thread.canReply = false;
		thread.comments = [comment];

		// 点击glutter bar中的图标，comment能够自动展开
		this.commentRanges.push(new vscode.Range(endPosition, endPosition));

		// 跟踪评论线程
		this.commentThreads.push(thread);
	}

	private deleteThread(threadUuid: string) {
		const thread = this.theadMap.get(threadUuid);
		if (thread == undefined) {
			return;
		}
		const currentIndex = this.commentThreads.indexOf(thread);
		if (currentIndex == -1) {
			return;
		}

		this.commentThreads.splice(currentIndex, 1);
		this.commentRanges.splice(currentIndex, 1);
		this.theadMap.delete(threadUuid);
		HarmonyPilotCommentCollectionProvider.removeThread(thread);
		thread.dispose();
	}

	private createThread(fsPath: string, startPosition: vscode.Position, endPosition: vscode.Position) {
		const thread = this.commentController.createCommentThread(
			vscode.Uri.file(fsPath), // 固定的本地文件URI
			new vscode.Range(startPosition, endPosition), // 第二行的range
			[] // Start with empty comments array
		);

		// Set thread properties to make it expand when clicked
		// thread.collapsibleState = vscode.CommentThreadCollapsibleState.Expanded;

		return thread;
	}

	private createComment(threadUuid: string, markdownContent:string, originalString:string, thread: vscode.CommentThread, replaceString: string, label?: string) {
		// 增加换行线
		markdownContent += "\n\n---\n";
		// 增加diff
		markdownContent += "```diff\n";
		// 分割原始字符串为多行，每行前添加-前缀
		const originalLines = originalString.split('\n');
		for (const line of originalLines) {
			markdownContent += `- ${line}\n`;
		}
		const replaceLines = replaceString.split('\n');
		for (const line of replaceLines) {
			markdownContent += `+ ${line}\n`;
		}
		markdownContent += "```\n";
		// 增加换行线
		markdownContent += "\n\n---\n";
		// 增加模拟按钮
		
		const args: [string, number?] = [threadUuid];
		const argsContent = encodeURIComponent(JSON.stringify(args));

		markdownContent += `[\[Apply And Go To Next\]](command:harmonypilot.applyAndGoToNext?${argsContent})`;
		markdownContent += "  |  ";
		markdownContent += `[\[Discard And Go To Next\]](command:harmonypilot.discardAndGoToNext?${argsContent})`;

		const comment = new HarmonyPilotComment(
			this.functionName,
			label == undefined ? "" : label,
			new vscode.MarkdownString(markdownContent),
			vscode.CommentMode.Preview,
			replaceString,
			thread,
			undefined
		);

		return comment;
	}

	public goToPreviousComment(threadUuid: string) {
		if (this.commentThreads.length === 0) {
			return false;
		}
		const thread = this.theadMap.get(threadUuid);
		if (thread == undefined) {
			return false;
		}
		const previousThread = this.commentThreads[this.commentThreads.indexOf(thread) + 1];
		if (previousThread == undefined) {
			// 显示通知，告知用户已经到达第一个评论
			vscode.window.showInformationMessage('You have reached the first comment.');
			return false;
		}

		thread.collapsibleState = vscode.CommentThreadCollapsibleState.Collapsed;
		previousThread.collapsibleState = vscode.CommentThreadCollapsibleState.Expanded;
	}

	// 跳转到下一个评论
	public goToNextComment(threadUuid: string) {
		if (this.commentThreads.length === 0) {
			return false;
		}
		const thread = this.theadMap.get(threadUuid);
		if (thread == undefined) {
			return false;
		}
		const nextThread = this.commentThreads[this.commentThreads.indexOf(thread) - 1];
		if (nextThread == undefined) {
			// 显示通知，告知用户已经到达最后一个评论
			vscode.window.showInformationMessage('You have reached the last comment.');
			return false;
		}

		thread.collapsibleState = vscode.CommentThreadCollapsibleState.Collapsed;
		nextThread.collapsibleState = vscode.CommentThreadCollapsibleState.Expanded;
	}
	
	// 应用更改并跳转到下一个评论
	public async applyAndGoToNext(threadUuid: string) {
		const thread = this.theadMap.get(threadUuid);
		if (thread == undefined) {
			return;
		}
		const currentIndex = this.commentThreads.indexOf(thread);
		if (currentIndex == -1) {
			return;
		}
		
		// 获取文档和替换信息
		const uri = thread.uri;
		const startPosition = thread.range.start;
		const endPosition = thread.range.end;
		
		// 获取替换字符串
		const comment = thread.comments[0];
		if (comment instanceof HarmonyPilotComment) {
			try {
				// 打开文档
				const document = await vscode.workspace.openTextDocument(uri);
				const replaceString = comment.replaceString;
				// 创建编辑
				const edit = new vscode.WorkspaceEdit();
				const range = new vscode.Range(startPosition, endPosition);
				// 应用替换
				edit.replace(uri, range, replaceString);
				await vscode.workspace.applyEdit(edit);
			} catch (error) {
				vscode.window.showErrorMessage(`Failed to apply changes: ${error}`);
			}
		}
		
		// 然后跳转到下一个评论
		this.goToNextComment(threadUuid);
		this.deleteThread(threadUuid);
	}

	public discardAndGoToNext(threadUuid: string) {
		// 这里可以添加丢弃更改的逻辑
		// ...
		
		// 然后跳转到下一个评论
		this.goToNextComment(threadUuid);
		this.deleteThread(threadUuid);
	}

	/**
	 * 清理HarmonyPilotCommentCollection中的相关数据
	 * 每次命令调用之前，需要调用此方法
	*/
	public clear() {
		// 清理HarmonyPilotCommentCollectionProvider中的相关数据
		this.commentThreads.forEach(thread => {
			HarmonyPilotCommentCollectionProvider.removeThread(thread);
		});
	
		// 清理this中的相关数据
		this.commentThreads.forEach(thread => {
			thread.dispose();
		});
		this.commentThreads = [];
		this.theadMap.clear();
		this.commentRanges = [];
	}
}

